<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Widgets II in GTK#</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, GTK#, Widgets, C#, programming, Linux">
<meta name="description" content="In this part of the GTK# tutorial, we continue
describing of widgets.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Widgets II in GTK#</h1>

<p>
In this part of the GTK# programming tutorial, we continue introducing GTK# widgets.
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
We will cover the Entry widget, the Scale widget, ToggleButton and Calendar widget. 
</p>


<h2>Entry</h2>

<p>
The <code>Entry</code> is a single line text entry field. This widget is used 
to enter textual data. 
</p>

<div class="codehead">entry.cs</div> 
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 
    Label label;

    public SharpApp() : base("Entry")
    {
        SetDefaultSize(250, 200);
        SetPosition(WindowPosition.Center);
        BorderWidth = 7;
        DeleteEvent += delegate { Application.Quit(); };
        
        label = new Label("...");

        Entry entry = new Entry();
        entry.Changed += OnChanged;

        Fixed fix = new Fixed();
        fix.Put(entry, 60, 100);
        fix.Put(label, 60, 40);

        Add(fix);

        ShowAll();
    }

    void OnChanged(object sender, EventArgs args)
    {
        Entry entry = (Entry) sender;
        label.Text = entry.Text;
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
This example shows an entry widget and a label. The text that we key in the 
entry is displayed immediately in the label control. 
</p>

<pre class="explanation">
Entry entry = new Entry();
</pre>

<p>
<code>Entry</code> widget is created. 
</p>

<pre class="explanation">
entry.Changed += OnChanged;
</pre>

<p>
If the text in the <code>Entry</code> widget is changed,
we call the <code>OnChanged()</code> method.
</p>

<pre class="explanation">
void OnChanged(object sender, EventArgs args)
{
    Entry entry = (Entry) sender;
    label.Text = entry.Text;
}
</pre>

<p>
We get the text from the <code>Entry</code> widget and
set it to the label. 
</p>

<img src="/img/gui/sharpgtk/entry.png" alt="Entry Widget">
<div class="figure">Figure: Entry Widget</div>



<h2>Scale</h2>

<p>
The <code>Scale</code> is a widget, that lets the user graphically select a value 
by sliding a knob within a bounded interval. Our example will show a volume control. 
</p>

<div class="codehead">hscale.cs</div> 
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 
    Gdk.Pixbuf mute, min, med, max;
    Image image;

    public SharpApp() : base("Scale")
    {
        SetDefaultSize(260, 150);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        HScale scale = new HScale(0, 100, 1);
        scale.SetSizeRequest(160, 35);
        scale.ValueChanged += OnChanged;

        LoadPixbufs();

        image = new Image(mute);

        Fixed fix = new Fixed();
        fix.Put(scale, 20, 40);
        fix.Put(image, 219, 50);

        Add(fix);

        ShowAll();
    }

    void LoadPixbufs() 
    {
        try {
            mute = new Gdk.Pixbuf("mute.png");
            min = new Gdk.Pixbuf("min.png");
            med = new Gdk.Pixbuf("med.png");
            max = new Gdk.Pixbuf("max.png");
        } catch {
            Console.WriteLine("Error reading Pixbufs");
            Environment.Exit(1);
        }
    }

    void OnChanged(object obj, EventArgs args)
    {
        HScale scale = (HScale) obj;
        double val = scale.Value;

        if (val == 0) {
            image.Pixbuf = mute;
        } else if (val > 0 &amp;&amp; val <= 30) {
            image.Pixbuf = min;
        } else if (val > 30 &amp;&amp; val < 80) {
            image.Pixbuf = med;
        } else {
            image.Pixbuf = max;
        }
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
In the example above, we have  <code>HScale</code> and 
<code>Image</code> widgets. By dragging the scale we change the image
on the <code>Image</code> widget.
</p>

<pre class="explanation">
HScale scale = new HScale(0, 100, 1);
</pre>

<p>
<code>HScale</code> widget is created. The parameters
are lower boundary, upper boundary and step. 
</p>

<pre class="explanation">
HScale scale = (HScale) obj;
double val = scale.Value;
</pre>

<p>
In the <code>OnChange()</code> method we obtain the
value of the scale widget. 
</p>

<pre class="explanation">
if (val == 0) {
    image.Pixbuf = mute;
} else if (val > 0 &amp;&amp; val <= 30) {
    image.Pixbuf = min;
} else if (val > 30 &amp;&amp; val < 80) {
    image.Pixbuf = med;
} else {
image.Pixbuf = max;
}
</pre>

<p>
Depending on the obtained value, we change the picture in
the image widget. 
</p>

<img src="/img/gui/sharpgtk/scale.png" alt="HScale Widget">
<div class="figure">Figure: HScale Widget</div>



<h2>ToggleButton</h2>

<p>
<code>ToggleButton</code> is a button that has two states. Pressed and not pressed. 
You toggle between these two states by clicking on it. There are situations where 
this functionality fits well. 
</p>

<div class="codehead">togglebuttons.cs</div>
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 
    DrawingArea darea;
    Gdk.Color col;

    public SharpApp() : base("ToggleButtons")
    {
        col = new Gdk.Color(0, 0, 0);

        SetDefaultSize(350, 240);
        SetPosition(WindowPosition.Center);
        BorderWidth = 7;
        DeleteEvent += delegate { Application.Quit(); };
        
        ToggleButton red = new ToggleButton("Red");
        red.SetSizeRequest(80, 35);
        red.Clicked += OnRed;

        ToggleButton green = new ToggleButton("Green");
        green.SetSizeRequest(80, 35);
        green.Clicked += OnGreen;

        ToggleButton blue = new ToggleButton("Blue");
        blue.SetSizeRequest(80, 35);
        blue.Clicked += OnBlue;

        darea = new DrawingArea();
        darea.SetSizeRequest(150, 150);
        darea.ModifyBg(StateType.Normal, col);

        Fixed fix = new Fixed();
        fix.Put(red, 30, 30);
        fix.Put(green, 30, 80);
        fix.Put(blue, 30, 130);
        fix.Put(darea, 150, 30);

        Add(fix);

        ShowAll();
    }

    void OnRed(object sender, EventArgs args) 
    {
        ToggleButton tb = (ToggleButton) sender;
        
        if (tb.Active) {
            col.Red = 65535; 
        } else {
            col.Red = 0;
        }

        darea.ModifyBg(StateType.Normal, col);         
    }

    void OnGreen(object sender, EventArgs args) 
    {
        ToggleButton tb = (ToggleButton) sender;

        if (tb.Active) {
            col.Green = 65535; 
        } else {
            col.Green = 0;
        }
        
        darea.ModifyBg(StateType.Normal, col);
    }

    void OnBlue(object sender, EventArgs args) 
    {
        ToggleButton tb = (ToggleButton) sender;

        if (tb.Active) {
            col.Blue = 65535; 
        } else {
            col.Blue = 0;
        }

        darea.ModifyBg(StateType.Normal, col);
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
In our example, we show three toggle buttons and a <code>DrawingArea</code>. 
We set the background color of the area to black. The togglebuttons will toggle the red, 
green and blue parts of the color value. The background color will depend on which
togglebuttons we have pressed. 
</p>

<pre class="explanation">
col = new Gdk.Color(0, 0, 0);
</pre>

<p>
This is the color value that is going to be updated with the toggle buttons. 
</p>

<pre class="explanation">
ToggleButton red = new ToggleButton("Red");
red.SetSizeRequest(80, 35);
red.Clicked += OnRed;
</pre>

<p>
The <code>ToggleButton</code> widget is created. We set it's size
to 80x35 pixels. Each of the toggle buttons has it's own handler method. 
</p>

<pre class="explanation">
darea = new DrawingArea();
darea.SetSizeRequest(150, 150);
darea.ModifyBg(StateType.Normal, col);
</pre>

<p>
The <code>DrawingArea</code> widget is the widget, that
displays the color, mixed by the toggle buttons. At start, it shows
black color. 
</p>


<pre class="explanation">
if (tb.Active) {
    col.Red = 65535; 
} else {
    col.Red = 0;
}
</pre>

<p>
We update the red part of the color according to the
value of the <code>Active</code> property.
</p>

<pre class="explanation">
darea.ModifyBg(StateType.Normal, col);
</pre>

<p>
We update the color of the <code>DrawingArea</code> widget. 
</p>

<img src="/img/gui/sharpgtk/togglebuttons.png" alt="ToggleButton widget">
<div class="figure">Figure: ToggleButton widget</div>

<h2>Calendar</h2>

<p>
Our final widget is the <code>Calendar</code> widget. It is used to 
work with dates.
</p>

<div class="codehead">calendar.cs</div>
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 
    private Label label;

    public SharpApp() : base("Calendar")
    {
        SetDefaultSize(300, 270);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        label = new Label("...");

        Calendar calendar = new Calendar();
        calendar.DaySelected += OnDaySelected;

        Fixed fix = new Fixed();
        fix.Put(calendar, 20, 20);
        fix.Put(label, 40, 230);

        Add(fix);

        ShowAll();
    }

    void OnDaySelected(object sender, EventArgs args)
    {
        Calendar cal = (Calendar) sender;
        label.Text = cal.Month + 1 + "/" + cal.Day + "/" + cal.Year;
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
We have the <code>Calendar</code> widget and a <code>Label</code>.
The selected day from the calendar is shown in the label. 
</p>

<pre class="explanation">
Calendar calendar = new Calendar();
</pre>

<p>
<code>Calendar</code> widget is created. 
</p>

<pre class="explanation">
Calendar cal = (Calendar) sender;
label.Text = cal.Month + 1 + "/" + cal.Day + "/" + cal.Year;
</pre>

<p>
In the <code>OnDaySelected()</code> method we get the referece 
to the <code>Calendar</code> widget, and update the label to 
the currently selected date. 
</p>

<img src="/img/gui/sharpgtk/calendar.png" alt="Calendar">
<div class="figure">Figure: Calendar</div>


<p>
In this chapter, we finished talking about the GTK# widgets. 
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<br>

<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified January 23, 2009  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>


